package com.dmai.capacity.platform.user.controller;

import java.util.List;
import java.util.Map;

import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.dmai.capacity.platform.common.annotation.Inner;
import com.dmai.capacity.platform.common.annotation.LoginUser;
import com.dmai.capacity.platform.common.dto.PageResult;
import com.dmai.capacity.platform.common.dto.ResponseEntity;
import com.dmai.capacity.platform.common.exception.BusinessException;
import com.dmai.capacity.platform.common.model.LoginAppUser;
import com.dmai.capacity.platform.common.model.SysRole;
import com.dmai.capacity.platform.common.model.SysUser;
import com.dmai.capacity.platform.log.annotation.AuditLog;
import com.dmai.capacity.platform.user.service.ISysUserService;

import io.vavr.control.Try;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;


@Slf4j
@RestController
public class SysUserController {
    private static final String ADMIN_CHANGE_MSG = "超级管理员不给予修改";

    @Autowired
    private ISysUserService sysUserService;

    /**
     * 当前登录用户 LoginAppUser
     *
     * @param user
     * @return
     */
    @Inner
    @GetMapping("/users/current")
    public ResponseEntity<LoginAppUser> getLoginAppUser(@LoginUser(isFull = true) SysUser user) {
        return ResponseEntity.succeed(sysUserService.getLoginAppUser(user));
    }

    /**
     * 查询用户实体对象SysUser
     *
     * @param username
     * @return
     */
    @Inner
    @GetMapping(value = "/users/name/{username}")
    @Cacheable(value = "user", key = "#username", unless = "#result == null")
    public SysUser selectByUsername(@PathVariable String username) {
        return sysUserService.selectByUsername(username);
    }

    /**
     * 查询用户登录对象LoginAppUser
     *
     * @param username
     * @return
     */
    @Inner
    @GetMapping(value = "/users-anon/login", params = "username")
    public LoginAppUser findByUsername(String username) {
        return sysUserService.findByUsername(username);
    }

    /**
     * 通过手机号查询用户、角色信息
     *
     * @param mobile 手机号
     * @return
     */
    @Inner
    @GetMapping(value = "/users-anon/mobile", params = "mobile")
    public LoginAppUser findByMobile(String mobile) {
        return sysUserService.findByMobile(mobile);
    }

    /**
     * 根据userId查询用户信息
     *
     * @param userId
     * @return
     */
    @Inner
    @GetMapping(value = "/users-anon/userId", params = "userId")
    public LoginAppUser findByUserId(String userId) {
        return sysUserService.findByUserId(userId);
    }

    /**
     * 根据OpenId查询用户信息
     *
     * @param openId
     * @return
     */
    @Inner
    @GetMapping(value = "/users-anon/openId", params = "openId")
    public LoginAppUser findByOpenId(String openId) {
        return sysUserService.findByOpenId(openId);
    }


    /***
     * 根据id查询用户
     * @param id
     * @return
     */
    @GetMapping("/users/{id}")
    public ResponseEntity<LoginAppUser> findUserById(@PathVariable Long id) {
        return ResponseEntity.succeed(sysUserService.getLoginAppUser(sysUserService.getById(id)));
    }

    /**
     * 获取用户的角色
     *
     * @param
     * @return
     */
    @GetMapping("/users/{id}/roles")
    public List<SysRole> findRolesByUserId(@PathVariable Long id) {
        return sysUserService.findRolesByUserId(id);
    }

    /**
     * 用户查询
     *
     * @param params
     * @return
     */
    @GetMapping("/users")
    @AuditLog(operation = " #sysUser.username  + '查看了用户列表'")
    public PageResult<SysUser> findUsers(@RequestParam Map<String, Object> params,
                                         @LoginUser(isFull = true) SysUser sysUser) {
        return sysUserService.findUsers(params);
    }

    /**
     * 修改用户状态
     *
     * @param params
     * @return
     */
    @GetMapping("/users/updateEnabled")
    public ResponseEntity updateEnabled(@RequestParam Map<String, Object> params) {
        Long id = MapUtils.getLong(params, "id");
        if (checkAdmin(id)) {
            return ResponseEntity.failed(ADMIN_CHANGE_MSG);
        }

        Try.of(() -> sysUserService.updateEnabled(params)).onFailure(ex -> log.error("user-updateEnabled-error", ex))
                .getOrElseThrow(item -> new BusinessException("操作失败"));

        return ResponseEntity.succeed("操作成功");

    }

    /**
     * 管理后台，给用户重置密码
     *
     * @param id
     */
    @PutMapping(value = "/users/{id}/password")
    public ResponseEntity resetPassword(@PathVariable Long id) {
        if (checkAdmin(id)) {
            return ResponseEntity.failed(ADMIN_CHANGE_MSG);
        }

        Try.of(() -> sysUserService.updatePassword(id, null, null))
                .onFailure(ex -> log.error("user-resetPassword-error", ex))
                .getOrElseThrow(item -> new BusinessException("重置失败"));

        return ResponseEntity.succeed("重置成功");
    }

    /**
     * 用户自己修改密码
     */
    @PutMapping(value = "/users/password")
    public ResponseEntity resetPassword(@RequestBody SysUser sysUser) {

        if (checkAdmin(sysUser.getId())) {
            return ResponseEntity.failed(ADMIN_CHANGE_MSG);
        }

        Try.of(() -> sysUserService.updatePassword(sysUser.getId(), sysUser.getOldPassword(), sysUser.getNewPassword()))
                .onFailure(ex -> log.error("user-resetPassword-error", ex))
                .getOrElseThrow(item -> new BusinessException("重置失败"));

        return ResponseEntity.succeed("重置成功");

    }

    /**
     * 删除用户
     *
     * @param id
     */
    @DeleteMapping(value = "/users/{id}")
    public ResponseEntity delete(@PathVariable Long id) {
        if (checkAdmin(id)) {
            return ResponseEntity.failed(ADMIN_CHANGE_MSG);
        }

        Try.of(() -> sysUserService.delUser(id)).onFailure(ex -> log.error("user-delete-error", ex))
                .getOrElseThrow(item -> new BusinessException("删除失败"));

        return ResponseEntity.succeed("删除成功");
    }

    /**
     * 新增or更新
     *
     * @param sysUser
     * @return
     */
    @SneakyThrows
    @PostMapping("/users/saveOrUpdate")
    @CacheEvict(value = "user", key = "#sysUser.username")
    @AuditLog(operation = "'新增或更新用户:' + #sysUser.username")
    public ResponseEntity saveOrUpdate(@RequestBody SysUser sysUser) {

        Try.of(() -> sysUserService.saveOrUpdateUser(sysUser)).onFailure(ex -> log.error("user-saveOrUpdate-error", ex))
                .getOrElseThrow(item -> new BusinessException("操作失败"));

        return ResponseEntity.succeed("操作成功");

    }


    /**
     * 是否超级管理员
     */
    private boolean checkAdmin(long id) {
        return id == 1L;
    }
}
